home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / xlib04.zip / XCLIPPBM.ASM < prev    next >
Assembly Source File  |  1992-11-12  |  12KB  |  496 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XCLIPPBM
  3. ;
  4. ; This module was written by Matthew MacKenzie
  5. ; matm@eng.umd.edu
  6. ;
  7. ; Clipped transfer of planar bitmaps from system memory to video memory.
  8. ;
  9. ; Compile with TASM.
  10. ; C near-callable.
  11. ;
  12. ; ****** XLIB - Mode X graphics library                ****************
  13. ; ******                                               ****************
  14. ; ****** Written By Themie Gouthas                     ****************
  15. ;
  16. ; egg@dstos3.dsto.gov.au
  17. ; teg@bart.dsto.gov.au
  18. ;-----------------------------------------------------------------------
  19.  
  20. include xlib.inc
  21. include xclippbm.inc
  22.  
  23.  
  24.     .data
  25.  
  26.     align 2
  27.  
  28. ; global clipping variables
  29. _TopBound       dw      (?)
  30. _BottomBound    dw      (?)
  31. _LeftBound      dw      (?)
  32. _RightBound     dw      (?)
  33.  
  34. ; VGA plane masks
  35. ColumnMask      db      011h,022h,044h,088h
  36.  
  37. ; bit delay timers
  38. LeftDelay       db      0, 1, 2, 4
  39. RightDelay      db      0, 4, 2, 1
  40.  
  41.  
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. ; _x_clip_pbm
  44. ;
  45. ; C near-callable as:
  46. ;
  47. ; void x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  48. ;
  49. ; Bitmap is a planar bitmap, in the regular Xlib format.
  50. ;
  51. ; ax, bx, cx, and dx go south.
  52.  
  53.     .code
  54.  
  55.     public _x_clip_pbm
  56.     align   2
  57. _x_clip_pbm proc
  58. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  59. LOCAL   left_counter, right_counter,column,clipped_height,clipped_width,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk
  60. ; Tasm 1.0 does not allow the \ line continuation
  61. ;LOCAL   left_counter:word, right_counter:word, \
  62. ;        column:word, clipped_height:word, clipped_width:word, \
  63. ;        screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  64. ;        VGA_mask:word, width_copy, height_temp:word, \
  65. ;        screen_width:word=LocalStk
  66.  
  67.     push bp
  68.     mov bp, sp
  69.     sub sp, LocalStk
  70.     push si
  71.     push di
  72.     push ds
  73.  
  74. ; sociopathic cases: are the clipping bounds out of order?
  75.     mov ax, _TopBound
  76.     cmp ax, _BottomBound
  77.     jg @@GetOut
  78.     mov ax, _LeftBound
  79.     cmp ax, _RightBound
  80.     jle @@ReasonableAndProper
  81. @@GetOut:
  82.     jmp @@OuttaHere     ; for conditional branches
  83.  
  84. @@ReasonableAndProper:
  85.  
  86. ; we need to use both the tables in ds and the height and width of the bitmap
  87.     les si, Bitmap
  88.  
  89. ; vertical position
  90.     xor cx, cx
  91.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  92.     xor ax, ax
  93.     mov al, byte ptr es:[si] ; width of bitmap
  94.     mul cx
  95.     mov bitmap_size, ax
  96.     mov ax, Y
  97.     cmp ax, _BottomBound ; top edge below clipping box?
  98.     jg @@GetOut
  99.  
  100.     mov bx, cx
  101.     add bx, ax
  102.     dec bx              ; bottom edge = Y + height - 1
  103.     cmp bx, _TopBound
  104.     jl @@GetOut
  105.     sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound
  106.     jle @@NoBottomBound
  107.     sub cx, bx          ; clip bottom margin from height
  108. @@NoBottomBound:
  109.     mov bx, _TopBound
  110.     sub bx, ax          ; top margin = TopBound - Y
  111.     jle @@NoTopBound
  112.     add ax, bx          ; top edge = Y + top margin
  113.     sub cx, bx          ; clip top margin from height
  114.     jmp @@KeepMargin
  115. @@NoTopBound:
  116.     xor bx, bx
  117. @@KeepMargin:
  118.     mov clipped_height, cx
  119.  
  120.     mul _ScrnLogicalByteWidth
  121.     mov di, ax
  122.     add di, ScreenOffs  ; row of upper-left corner of blit
  123.  
  124.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  125.     mov ax, cx
  126.     mul bx
  127.     add si, ax
  128.     add si, 2           ; starting position in bitmap
  129.  
  130. ; horizontal position
  131.     mov width_copy, cx
  132.     mov dx, X
  133.     cmp dx, _RightBound
  134.     jg @@GetOut
  135.     mov dx, 0           ; unclipped value for right delay
  136.  
  137.     mov ax, cx
  138.     shl ax, 2           ; width in pixels
  139.     add ax, X
  140.     dec ax              ; right edge = X + width in pixels - 1
  141.     cmp ax, _LeftBound
  142.     jl @@GetOut
  143.     sub ax, _RightBound  ; right margin = right edge - RightBound
  144.     jle @@NoRightBound
  145.     mov bx, ax
  146.     and bx, 3
  147.     mov dl, RightDelay[bx]
  148.     shr ax, 2
  149.     sub cx, ax          ; subtract clipped bytes from width
  150. @@NoRightBound:
  151.     mov right_counter, dx
  152.     mov dx, 0           ; unclipped value for left delay
  153.     mov ax, _LeftBound
  154.     sub ax, X           ; left margin = LeftBound - X
  155.     jle @@NoLeftBound
  156.     mov bx, ax
  157.     and bx, 3
  158.     mov dl, LeftDelay[bx]
  159.     add ax, 3
  160.     shr ax, 2           ; left margin/4, rounded up
  161.     sub cx, ax          ; subtract clipped bytes from width
  162.     add si, ax          ; move starting position in bitmap past margin
  163.     add di, ax          ; move starting position on screen past margin
  164. @@NoLeftBound:
  165.     mov left_counter, dx
  166.     mov clipped_width, cx
  167.  
  168.     mov ax, X           ; add x coordinate to screen position
  169.     mov bx, ax
  170.     shr ax, 2
  171.     add di, ax
  172.  
  173.     mov dx, SC_INDEX
  174.     mov al, MAP_MASK
  175.     out dx, al
  176.     inc dx
  177.  
  178.     and bx, 3           ; initial mask
  179.     xor ax, ax
  180.     mov al, ColumnMask[bx]
  181.     mov VGA_mask, ax
  182.     out dx, al          ; initial mask
  183.  
  184.     mov column, 4
  185.     mov bitmap_pos, si
  186.     mov screen_pos, di
  187.     mov ax, _ScrnLogicalByteWidth
  188.     mov screen_width, ax ; since we move ds
  189.  
  190. ; we've used all our tables, so we can change ds to point to the bitmap,
  191. ; and es to point to the screen
  192.     mov ds, word ptr [Bitmap + 2]
  193.     mov ax, SCREEN_SEG
  194.     mov es, ax
  195.  
  196.     cld                 ; strings go forward
  197.     mov bx, width_copy
  198.     sub bx, clipped_width ; bytes to advance one line in bitmap
  199.  
  200. ; let's actually draw something for a change
  201. @@WritePlane:
  202.     mov ax, clipped_height
  203.     mov height_temp, ax
  204.     mov dx, screen_width
  205.     sub dx, clipped_width ; bytes to advance one line across screen
  206.  
  207. @@WriteLine:
  208.     mov cx, clipped_width
  209.     shr cx, 1
  210.     rep movsw           ; in they went, two by two...
  211.     adc cx, 0
  212.     rep movsb           ; catch stray last byte, if it's there
  213.     add si, bx          ; advance one bitmap line
  214.     add di, dx          ; advance one screen line
  215.  
  216.     dec height_temp
  217.     jnz @@WriteLine
  218.  
  219.     dec column
  220.     jz @@OuttaHere      ; only four columns per customer, please
  221.     mov dx, SC_INDEX + 1
  222.     rol byte ptr VGA_mask, 1
  223.     adc screen_pos, 0   ; add to location if we've wrapped to plane 0
  224.     mov al, byte ptr VGA_mask
  225.     out dx, al          ; set VGA for next column
  226.  
  227.     shr right_counter, 1
  228.     jnc @@NoRightCounter
  229.     dec clipped_width   ; cut off right edge for later planes
  230.     inc bx
  231. @@NoRightCounter:
  232.     shr left_counter, 1
  233.     jnc @@NoLeftCounter
  234.     inc clipped_width   ; add to left edge for later planes
  235.     dec bx
  236.     dec bitmap_pos
  237.     dec screen_pos
  238. @@NoLeftCounter:
  239.     mov si, bitmap_pos
  240.     add si, bitmap_size
  241.     mov bitmap_pos, si
  242.     mov di, screen_pos
  243.     jmp @@WritePlane
  244.  
  245. @@OuttaHere:
  246.     pop ds
  247.     pop di
  248.     pop si
  249.     mov sp, bp
  250.     pop bp
  251.  
  252.     ret
  253. _x_clip_pbm endp
  254.  
  255.  
  256. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  257. ; _x_clip_masked_pbm
  258. ;
  259. ; C near-callable as:
  260. ;
  261. ; void x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  262. ;
  263. ; Bitmap is a planar bitmap, in the regular Xlib format.
  264. ; The width of the bitmap cannot be greater than 90 bytes, however.
  265. ; Ain't that just criminal?
  266. ;
  267. ; ax, bx, cx, and dx go south.
  268.  
  269.  
  270. ; one branch per pixel is more than enough -- we'll unroll the line-writing
  271. ; loop all the way to try to get a little speed (at the expense, as usual,
  272. ; of a chunk of memory)
  273.  
  274. MaskedPoint macro offset
  275.     mov al, [si + offset]
  276.     or al, al
  277.     jz $+6
  278.     mov es:[di + offset], al
  279.     endm
  280.  
  281. MaskedPointSize     equ     11
  282.  
  283.     public _x_clip_masked_pbm
  284.     align   2
  285. _x_clip_masked_pbm proc
  286. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  287. ; Tasm 1.0 does not allow the \ line continuation
  288. LOCAL   left_counter,right_counter,column:word,clipped_height,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk
  289. ;LOCAL   left_counter:word, right_counter:word, \
  290. ;        column:word, clipped_height:word, \
  291. ;        screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  292. ;        VGA_mask:word, width_copy, height_temp:word, \
  293. ;        screen_width:word=LocalStk
  294.     push bp
  295.     mov bp, sp
  296.     sub sp, LocalStk
  297.     push si
  298.     push di
  299.     push ds
  300.  
  301. ; sociopathic cases: are the clipping bounds out of order?
  302.     mov ax, _TopBound
  303.     cmp ax, _BottomBound
  304.     jg @@GetOut
  305.     mov ax, _LeftBound
  306.     cmp ax, _RightBound
  307.     jle @@ReasonableAndProper
  308. @@GetOut:
  309.     jmp @@OuttaHere     ; for conditional branches
  310.  
  311. @@ReasonableAndProper:
  312.  
  313. ; we need to use both the tables in ds and the height and width of the bitmap
  314.     les si, Bitmap
  315.  
  316. ; vertical position
  317.     xor cx, cx
  318.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  319.     xor ax, ax
  320.     mov al, byte ptr es:[si] ; width of bitmap
  321.     mul cx
  322.     mov bitmap_size, ax
  323.     mov ax, Y
  324.     cmp ax, _BottomBound ; top edge below clipping box?
  325.     jg @@GetOut
  326.  
  327.     mov bx, cx
  328.     add bx, ax
  329.     dec bx              ; bottom edge = Y + height - 1
  330.     cmp bx, _TopBound
  331.     jl @@GetOut
  332.     sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound
  333.     jle @@NoBottomBound
  334.     sub cx, bx          ; clip bottom margin from height
  335. @@NoBottomBound:
  336.     mov bx, _TopBound
  337.     sub bx, ax          ; top margin = TopBound - Y
  338.     jle @@NoTopBound
  339.     add ax, bx          ; top edge = Y + top margin
  340.     sub cx, bx          ; clip top margin from height
  341.     jmp @@KeepMargin
  342. @@NoTopBound:
  343.     xor bx, bx
  344. @@KeepMargin:
  345.     mov clipped_height, cx
  346.  
  347.     mul _ScrnLogicalByteWidth
  348.     mov di, ax
  349.     add di, ScreenOffs  ; row of upper-left corner of blit
  350.  
  351.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  352.     mov ax, cx
  353.     mul bx
  354.     add si, ax
  355.     add si, 2           ; starting position in bitmap
  356.  
  357. ; horizontal position
  358.     mov width_copy, cx
  359.     mov dx, X
  360.     cmp dx, _RightBound
  361.     jg @@GetOut
  362.     mov dx, 0           ; unclipped value for right delay
  363.  
  364.     mov ax, cx
  365.     shl ax, 2           ; width in pixels
  366.     add ax, X
  367.     dec ax              ; right edge = X + width in pixels - 1
  368.     cmp ax, _LeftBound
  369.     jl @@GetOut
  370.     sub ax, _RightBound ; right margin = right edge - RightBound
  371.     jle @@NoRightBound
  372.     mov bx, ax
  373.     and bx, 3
  374.     mov dl, RightDelay[bx]
  375.     shr ax, 2
  376.     sub cx, ax          ; subtract clipped bytes from width
  377. @@NoRightBound:
  378.     mov right_counter, dx
  379.     mov dx, 0           ; unclipped value for left delay
  380.     mov ax, _LeftBound
  381.     sub ax, X           ; left margin = LeftBound - X
  382.     jle @@NoLeftBound
  383.     mov bx, ax
  384.     and bx, 3
  385.     mov dl, LeftDelay[bx]
  386.     add ax, 3
  387.     shr ax, 2           ; left margin/4, rounded up
  388.     sub cx, ax          ; subtract clipped bytes from width
  389.     add si, ax          ; move starting position in bitmap past margin
  390.     add di, ax          ; move starting position on screen past margin
  391. @@NoLeftBound:
  392.     mov left_counter, dx
  393.     mov ax, cx
  394.     imul ax, (-1 * MaskedPointSize)
  395.     add ax, offset @@LineDone + 2
  396.     mov cx, ax          ; jump offset for plotting
  397.  
  398.     mov ax, X           ; add x coordinate to screen position
  399.     mov bx, ax
  400.     shr ax, 2
  401.     add di, ax
  402.  
  403.     mov dx, SC_INDEX
  404.     mov al, MAP_MASK
  405.     out dx, al
  406.     inc dx
  407.  
  408.     and bx, 3           ; initial mask
  409.     xor ax, ax
  410.     mov al, ColumnMask[bx]
  411.     mov VGA_mask, ax
  412.     out dx, al
  413.  
  414.     mov column, 4
  415.     mov bitmap_pos, si
  416.     mov screen_pos, di
  417.     mov ax, _ScrnLogicalByteWidth
  418.     mov screen_width, ax ; since we move ds
  419.  
  420. ; we've used all our tables, so we can change ds to point to the bitmap,
  421. ; and es to point to the screen
  422.     mov ds, word ptr [Bitmap + 2]
  423.     mov ax, SCREEN_SEG
  424.     mov es, ax
  425.  
  426.     mov bx, width_copy
  427.  
  428. ; let's actually draw something for a change
  429.     mov ax, clipped_height
  430.     mov height_temp, ax
  431.     mov dx, screen_width
  432.     jmp cx
  433.  
  434. ; 90 bottles of beer on the wall...
  435.     PointLoop = 89
  436.     rept 89
  437.         MaskedPoint PointLoop
  438.         PointLoop = PointLoop - 1
  439.     endm
  440. ; one bottle of beer...
  441.  
  442. ; final point needs a different branch offset, so we don't use MaskedPoint
  443.     mov al, [si]
  444.     or al, al
  445.     jz @@LineDone
  446.     mov es:[di], al
  447.  
  448. @@LineDone:
  449.     add si, bx          ; advance one bitmap line
  450.     add di, dx          ; advance one screen line
  451.     dec height_temp
  452.     jz @@PlaneDone
  453.     jmp cx
  454.  
  455. @@PlaneDone:
  456.     dec column
  457.     jz @@OuttaHere      ; only four columns per customer, please
  458.     mov dx, SC_INDEX + 1
  459.     rol byte ptr VGA_mask, 1
  460.     adc screen_pos, 0   ; move to new column if we've wrapped to plane 0
  461.     mov al, byte ptr VGA_mask
  462.     out dx, al          ; set VGA for next column
  463.  
  464.     shr right_counter, 1
  465.     jnc @@NoRightCounter
  466.     add cx, MaskedPointSize ; cut off right edge for later planes
  467. @@NoRightCounter:
  468.     shr left_counter, 1
  469.     jnc @@NoLeftCounter
  470.     sub cx, MaskedPointSize ; add to left edge for later planes
  471.     dec bitmap_pos
  472.     dec screen_pos
  473. @@NoLeftCounter:
  474.     mov si, bitmap_pos
  475.     add si, bitmap_size
  476.     mov bitmap_pos, si
  477.     mov di, screen_pos
  478.  
  479.     mov ax, clipped_height
  480.     mov height_temp, ax
  481.     mov dx, screen_width
  482.     jmp cx
  483.  
  484. @@OuttaHere:
  485.     pop ds
  486.     pop di
  487.     pop si
  488.     mov sp, bp
  489.     pop bp
  490.  
  491.     ret
  492. _x_clip_masked_pbm endp
  493.  
  494.     end
  495.  
  496.